package com.nbufe.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nbufe.common.security.utils.SecurityUtils;
import com.nbufe.domain.ResponseResult;
import com.nbufe.domain.dto.data.YearMonthRangeDto;
import com.nbufe.domain.dto.report.GenReportDto;
import com.nbufe.domain.dto.report.PageReportDto;
import com.nbufe.domain.entity.EmissionOrigin;
import com.nbufe.domain.entity.Process;
import com.nbufe.domain.entity.Reports;
import com.nbufe.domain.vo.PageVo;
import com.nbufe.domain.vo.report.DetailReportVo;
import com.nbufe.domain.vo.report.GenReportVo;
import com.nbufe.domain.vo.report.ReportAnswerVo;
import com.nbufe.domain.vo.report.TitleCodeVo;
import com.nbufe.enums.AppHttpCodeEnum;
import com.nbufe.exception.SystemException;
import com.nbufe.manager.AIManager;
import com.nbufe.mapper.*;
import com.nbufe.service.DataService;
import com.nbufe.service.ProcessService;
import com.nbufe.service.ReportsService;
import com.nbufe.utils.HttpContextUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 碳排放报告(Reports)表服务实现类
 *
 * @author luzhiheng
 * @since 2024-01-05 16:08:36
 */
@Service("reportsService")
public class ReportsServiceImpl extends ServiceImpl<ReportsMapper, Reports> implements ReportsService {

    @Value("${modelId.chart-vue}")
    private Long modelId;

    @Resource
    private AIManager aiManager;

    @Resource
    private FossilFuelMapper fossilFuelMapper;

    @Resource
    private IndustoryProduceMapper industoryProduceMapper;

    @Resource
    private FixCarbonMapper fixCarbonMapper;

    @Resource
    private ElectricHeatMapper electricHeatMapper;

    @Resource
    private ProcessService processService;

    @Resource
    private DataService dataService;

    @Override
    public ResponseResult genReport(GenReportDto dto) {

        StringBuilder csvData = new StringBuilder();
        csvData.append("年,月,工序,原料,碳排放量").append("\n");

        //todo ai
        List<String> dataRange = dto.getDateRange();
        String begin = dataRange.get(0);
        String end = dataRange.get(1);

        List<GenReportVo> csvList = new ArrayList<>();
        String[] split = begin.split("-");
        String[] split1 = end.split("-");
        List<GenReportVo> genReportVoList = fossilFuelMapper.queryYearMonthRangeCO2(new YearMonthRangeDto(split[0] + "-" + Integer.valueOf(split[1]), split1[0] + "-" + Integer.valueOf(split1[1])));
        Map<String, Object> fossiMap = new HashMap<>();
        for (GenReportVo vo : genReportVoList) {
            GenReportVo reportVo = new GenReportVo(vo.getYear(), vo.getMonth(), "燃料燃烧", vo.getProcess(), vo.getEmissionOrigin(), vo.getCarbonEmission());
            csvList.add(reportVo);
            fossiMap.put(vo.getYear() + "-" + vo.getMonth() + "-" + vo.getEmissionOrigin(), reportVo);
        }

        genReportVoList = industoryProduceMapper.queryYearMonthRangeCO2(new YearMonthRangeDto(split[0] + "-" + Integer.valueOf(split[1]), split1[0] + "-" + Integer.valueOf(split1[1])));
        for (GenReportVo vo : genReportVoList) {
            GenReportVo reportVo = new GenReportVo(vo.getYear(), vo.getMonth(), "工业生产", vo.getProcess(), vo.getEmissionOrigin(), vo.getCarbonEmission());
            csvList.add(reportVo);
        }

        genReportVoList = electricHeatMapper.queryYearMonthRangeCO2(new YearMonthRangeDto(split[0] + "-" + Integer.valueOf(split[1]), split1[0] + "-" + Integer.valueOf(split1[1])));
        for (GenReportVo vo : genReportVoList) {
            GenReportVo reportVo = new GenReportVo(vo.getYear(), vo.getMonth(), "电力热力", vo.getProcess(), vo.getEmissionOrigin(), vo.getCarbonEmission());
            csvList.add(reportVo);
        }

        genReportVoList = fixCarbonMapper.queryYearMonthRangeCO2(new YearMonthRangeDto(split[0] + "-" + Integer.valueOf(split[1]), split1[0] + "-" + Integer.valueOf(split1[1])));
        for (GenReportVo vo : genReportVoList) {
            GenReportVo reportVo = new GenReportVo(vo.getYear(), vo.getMonth(), "固碳产品", vo.getProcess(), vo.getEmissionOrigin(), vo.getCarbonEmission());
            csvList.add(reportVo);
        }

        csvList = csvList.stream().sorted((o1, o2) -> o1.getYear() - o2.getYear() + o1.getMonth() - o2.getMonth()).collect(Collectors.toList());


        for (GenReportVo vo : csvList) {
            csvData.append(vo.getYear()).append(",")
                    .append(vo.getMonth()).append(",")
                    .append(vo.getProcess()).append(",")
                    .append(vo.getEmissionOrigin()).append(",")
                    .append(vo.getCarbonEmission()).append("\n");
        }
        String answer = aiManager.doChat(modelId, csvData.toString());
        ReportAnswerVo vo = analyzeReport(answer);

        Reports reports = new Reports();
        reports.setReportType(0);
        reports.setReportTitle(dto.getName());
        reports.setReportContent(vo.getConclusion());
        reports.setReportCode(JSON.toJSONString(vo.getTitleCodeList()));
        reports.setStartDate(dto.getDateRange().get(0).substring(0, 7));
        reports.setEndDate(dto.getDateRange().get(1).substring(0, 7));
        reports.setCreateTime(new Date());
        reports.setDelFlag(0);
        this.save(reports);

//        ReportAnswerVo vo = analyzeReport("");
        return ResponseResult.okResult(vo);
    }

    @Override
    public ReportAnswerVo analyzeReport(String answer) {
        int isLeave = answer.lastIndexOf("======");
        String substring = answer.substring(0, isLeave);
        substring = substring.replaceAll("======", "");
        substring = substring.replaceAll("=", "");
        substring = substring.replaceAll("ECharts v5 Option配置", "");
        substring = substring.replaceAll("ECharts v5 option配置", "");


        ReportAnswerVo vo = new ReportAnswerVo();
        vo.setConclusion(substring);
        String codeStr = answer.substring(isLeave);
        List<TitleCodeVo> titleCodeVoList = new ArrayList<>();
        int i1 = codeStr.indexOf("1. ");
        int i2 = codeStr.indexOf("2. ");
        int i3 = codeStr.indexOf("3. ");
        int i4 = codeStr.indexOf("4. ");
        int i5 = codeStr.indexOf("5. ");
        System.out.println(codeStr.substring(i1, i2));
        System.out.println(codeStr.substring(i2, i3));
        System.out.println(codeStr.substring(i3, i4));
        System.out.println(codeStr.substring(i4, i5));
        System.out.println(codeStr.substring(i5));

        TitleCodeVo titleCodeVo = new TitleCodeVo(codeStr.substring(i1, i1 + 12).trim(), codeStr.substring(i1 + 12, i2).trim().replace("option1 =", ""));
        TitleCodeVo titleCodeVo1 = new TitleCodeVo(codeStr.substring(i2, i2 + 13).trim(), codeStr.substring(i2 + 13, i3).trim().replace("option2 =", ""));
        TitleCodeVo titleCodeVo2 = new TitleCodeVo(codeStr.substring(i3, i3 + 14).trim(), codeStr.substring(i3 + 14, i4).trim().replace("option3 =", ""));
        TitleCodeVo titleCodeVo3 = new TitleCodeVo(codeStr.substring(i4, i4 + 12).trim(), codeStr.substring(i4 + 12, i5).trim().replace("option4 =", ""));
        TitleCodeVo titleCodeVo4 = new TitleCodeVo(codeStr.substring(i5, i5 + 13).trim(), codeStr.substring(i5 + 13).trim().replace("option5 =", ""));

        titleCodeVoList.add(titleCodeVo);
        titleCodeVoList.add(titleCodeVo1);
        titleCodeVoList.add(titleCodeVo2);
        titleCodeVoList.add(titleCodeVo3);
        titleCodeVoList.add(titleCodeVo4);
        vo.setTitleCodeList(titleCodeVoList);

        return vo;
    }

    @Override
    public ResponseResult pageListReport(PageReportDto dto) {
        String tenantId = HttpContextUtils.getRequestHeader("Tenant-Id");
        LambdaQueryWrapper<Reports> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.hasText(tenantId)) {
            queryWrapper.eq(Reports::getTenantId, Integer.parseInt(tenantId));
        }

        Page<Reports> page = new Page<>(dto.getPage(), dto.getSize());
        this.page(page, queryWrapper);

        PageVo pageVo = new PageVo(page.getTotal(), page.getRecords());
        if (CollectionUtils.isEmpty(page.getRecords())) {
            pageVo.setTotal(0L);
        }
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult detailReport(Long id) {
        Reports reports = this.getById(id);
        if (reports == null) {
            throw new SystemException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        DetailReportVo vo = new DetailReportVo();
        vo.setId(reports.getId());
        vo.setReportType(reports.getReportType());
        vo.setReportTitle(reports.getReportTitle());
        vo.setReportContent(reports.getReportContent());
        List<TitleCodeVo> codeStrList = JSON.parseArray(reports.getReportCode(), TitleCodeVo.class);
        vo.setReportCodeList(codeStrList);
        vo.setStartDate(reports.getStartDate());
        vo.setEndDate(reports.getEndDate());
        vo.setCreateTime(reports.getCreateTime());

        return ResponseResult.okResult(vo);
    }

}

